<template>
  <!-- <img alt="Vue logo" src="./assets/logo.png" /> -->
  <!-- <HelloWorld msg="Hello Vue 3 + TypeScript + Vite" /> -->
  <div id="map"></div>
  <div id="code" v-if="codeVisible">
    <div class="code-btn" @click="exportPhoto">
      导出图片
    </div>
    <div class="code-btn" @click="openDialog">
      Json(保存)
    </div>
    <div class="code-btn" @click="getHistory">
      历史记录
    </div>
    <div class="code-btn" @click="resetMind">
      重置
    </div>
    <div class="code-btn" @click="timming">
      定时保存({{ timingSwitch ? '开' : '关'}})
    </div>
  </div>
  <el-dialog
    v-model="historyVisible"
    title="历史记录"
    width="calc(100vw - 80px)"
    :before-close="handleClose"
    :fullscreen="true"
  >
    <div class="flex">
      <div class="flex-list">
        <div class="history-list">
          <div :class="['history-list-item', historyActiveId === item.id ? 'history-list-item--active' : '']" v-for="item in historyList" :key="item.id">
            <span @click="getHistoryId(item.id)">{{ item.topic }}</span>
          </div>
        </div>
      </div>
      <div class="flex-json">
        <vue-json-pretty :path="'root'" :data="historyJson" />
      </div>
    </div>
    <template #footer>
      <span class="dialog-footer">
        <el-popconfirm title="你确定要删除么?" @confirm="delHistory" confirm-button-text="确定" cancel-button-text="取消" v-if="historyActiveId">
          <template #reference>
            <el-button size="small" >删 除</el-button>
          </template>
        </el-popconfirm>
        <!-- <el-button @click="delHistory"></el-button> -->
        <el-button v-if="historyActiveId" size="small" @click="confirmHistory">应 用</el-button>
        <el-button size="small" @click="handleClose">关 闭</el-button>
      </span>
    </template>
  </el-dialog>
  <el-dialog
    v-model="jsonVisible"
    title="JSON 可视化"
    width="calc(100vw - 80px)"
    :before-close="handleClose"
    :fullscreen="true"
  >
    <div class="flex-json--full">
      <vue-json-pretty :path="'root'" :data="mindJson" />
    </div>
    <template #footer>
      <span class="dialog-footer">
        <el-button size="small" @click="importJson">导 入</el-button>
        <el-popover
          placement="top-start"
          :width="200"
          trigger="hover"
          content="导出 json 文件"
        >
          <template #reference>
            <el-button size="small" @click="exportJson">导 出</el-button>
          </template>
        </el-popover>
        <el-popover
          placement="top-start"
          :width="200"
          trigger="hover"
          content="保存到utools数据库"
        >
          <template #reference>
            <el-button size="small" @click="saveJson(true)">保 存</el-button>
          </template>
        </el-popover>
        <el-button size="small" @click="handleClose">关 闭</el-button>
      </span>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
// This starter template is using Vue 3 <script setup> SFCs
// Check out https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup
// import HelloWorld from './components/HelloWorld.vue'
import { onMounted, ref, Ref } from 'vue'
// 思维导图
import MindElixir, { E } from "mind-elixir"
import painter from 'mind-elixir/dist/painter'
// json 格式化
import VueJsonPretty from 'vue-json-pretty';
import 'vue-json-pretty/lib/styles.css';

// uuid
import uuid from 'short-uuid'

import { ElMessageBox, ElMessage } from 'element-plus'

const utools = window.utools
const saveFile = window.saveFile
const readFile = window.readFile

const mindJson: Ref = ref({
  nodeData: {}
})
const codeVisible: Ref= ref(true)
const jsonVisible: Ref= ref(false)
// 历史记录显示
const historyVisible: Ref = ref(false)
// 历史记录json数据
const historyJson: Ref= ref({})
// 历史记录列表
const historyList: Ref = ref({})
// 当前历史记录ID
const historyActiveId: Ref = ref('')
const timingSwitch: Ref = ref(false)

let schule: any = null
// 最后一次历史记录
const last = ref({})
// 定义 思维导图 基本项
const options = {
  el: '#map',
  locale: 'zh_CN',
  direction: MindElixir.RIGHT,
  // create new map data
  data: MindElixir.new('主 题'),
  // or set as data that is return from `.getAllData()`
  // data: {...},
  draggable: true, // default true
  contextMenu: true, // default true
  toolBar: true, // default true
  nodeMenu: true, // default true
  keypress: true, // default true
  primaryNodeVerticalGap: 15, // default 25
  primaryNodeHorizontalGap: 15, // default 65
}

let mind: any = null
// 挂载
onMounted(() => {
  mind = new MindElixir(options)
  // mind.init()
  console.log('mind', mind)
  mind.init()
  // get a node
  E('node-id')
  mind.bus.addListener('selectNode', (node: any) => {
    console.log(node)
    codeVisible.value = false
  })
  mind.bus.addListener('unselectNode', (node: any) => {
    console.log(node)
    codeVisible.value = true
  })
  console.log('mind.bus', mind.bus)
  
})
// 获取json数据
const getJson = () => {
  console.log('获取数据')
  console.log('mind', mind.getAllData())
  mindJson.value = mind.getAllData().nodeData 
}
// 导出图片
const exportPhoto = () => {
  console.log('导出图片')
  // painter.exportSvg(mind,'file')
  // painter.exportPng(mind,'file')
  ElMessageBox.prompt('请输入导出图片名字', '提示', {
    confirmButtonText: '确认',
    cancelButtonText: '返回',
  })
    .then(({ value }) => {
      painter.exportPng(mind, value)
      ElMessage({
        type: 'success',
        message: `保存成功`,
        showClose: true
      })
    })
    .catch(() => {
      ElMessage({
        type: 'error',
        message: '保存失败',
        showClose: true
      })
    })
}
// 开启弹窗
const openDialog = () => {
  getJson()
  jsonVisible.value = true
}
// 关闭弹窗
const handleClose = () => {
  jsonVisible.value = false
  historyVisible.value = false
}
// 历史记录
const getHistory = () => {
  let allData = utools.db.allDocs()
 
  if (allData.length) {
    historyVisible.value = true
    historyList.value = allData
    historyActiveId.value ? getHistoryId(historyActiveId.value): ''
  } else {
    ElMessage({
      type: 'error',
      message: `暂无记录`,
      showClose: true
    })
  }
}
// 获取某一条历史记录
const getHistoryId = (id: string | number) => {
  historyActiveId.value = id
  historyJson.value = historyList.value.filter((ele: any) => {
    return ele.id === id
  })
}
// 删除记录
const delHistory = () => {
  if (historyActiveId.value === mindJson.value.id) {
    resetMind()
  }
  let res = utools.db.remove(historyActiveId.value)
  if (res.ok) {
    getHistory()
  }
}
// 重置思维导图
const resetMind = (data?: any) => {
  console.log('data resetMind', data.id)
  if (!data.id) {
    data = {
      topic: '主题',
      id: uuid.generate().toLowerCase(),
      parent: null,
    }
  } 
  mind.nodeData = data
  mind.refresh()
}
// 保存数据
const saveJson = (confirm: boolean) => {
  console.log('保存数据')
  if (confirm) {
    timingSwitch.value = false
    window.clearInterval(schule)
  }
  let data: any = {...mindJson.value}
  data._id = data.id
  data.parent = null
  console.log('mindJson', JSON.parse(JSON.stringify(data)))
  data = JSON.parse(JSON.stringify(data))
  // 查询数据
  let res = utools.db.get(data._id)
  if (res) {
    data._rev = res._rev
    data._id = res._id
    console.log('res', res)
  } else {
    delete data._rev
  }
  console.log('data' , data)
  let resPut = utools.db.put(data)
  if (resPut.ok) {
    ElMessage({
      type: 'success',
      message: `保存成功`,
      showClose: true
    })
    handleClose()
  } else {
    ElMessage({
      type: 'error',
      message: `保存失败`,
      showClose: true
    })
    handleClose()
  }
  
  console.log('resPut', resPut)
}
// 应用数据
const confirmHistory = () => {
  console.log('使用历史数据', JSON.parse(JSON.stringify(historyJson.value))[0])
  let data = JSON.parse(JSON.stringify(historyJson.value))[0]
  mind.nodeData = data
  mind.refresh()
  handleClose()
}

// 定时保存
const timming = () => {
  console.log('定时保存')
  if (!timingSwitch.value) {
    timingSwitch.value = true
    schule = setInterval(function() {
      getJson()
      saveJson(false)
    }, 1000 * 30)
  } else {
    timingSwitch.value = false
  }
}

const exportJson = () => {
  console.log('导出 json')
  let res = utools.showSaveDialog({ 
    title: '保存位置', 
    defaultPath: utools.getPath('downloads'),
    buttonLabel: '保存',
    filters: [{ 'name': 'json', extensions: ['json'] }],
  })
  saveFile(res, JSON.stringify(mindJson.value))
}

const importJson = () => {
  console.log('导入 json')
  let uPath = utools.showOpenDialog({ 
    filters: [{ 'name': 'json', extensions: ['json'] }], 
    properties: ['openFile']
  })[0]
  let res = JSON.parse(readFile(uPath))
  resetMind(res)
  handleClose()
}

// utools 增删改查
// 插件装配完成，仅进入执行一次
utools.onPluginReady(() => {
  // 获取所有数据
  // console.log('getData()',  utools.db.allDocs())
})

</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  /* margin-top: 60px; */
  background-color: #f6f6f6;
}
#map {
  height: 500px;
  width: 100%;
}
.map-container .map-canvas root tpc {
  margin-left: 10px;
}
#fullscreen {
  display: none;
}
#code {
  position: absolute;
  top: 30px;
  right: 30px;
  width: 80px;
  padding: 4px 6px;
  border: 1px solid #ccc;
  border-radius: 4px;
  background-color: #fff;
}
.code-btn {
  padding: 8px 0;
  margin-bottom: 8px;
  border-bottom: 1px solid #ccc;
  cursor: pointer;
  transition: all .3s cubic-bezier(0.215, 0.610, 0.355, 1);
}
.code-btn:last-child {
  border: 0;
  margin-bottom: 0;
}
.code-btn:hover {
  color: #fff;
  border: 0;
  background-color: rgba(255,161,161,1);
}
.flex {
  display: flex;
}
.flex-list {
  display: flex;
  flex-direction: column;
  width: 25%;
  height: calc(100vh - 180px);
  overflow: auto;
}
.flex-json {
  width: 75%;
  height: calc(100vh - 180px);
  overflow: auto;
}
.flex-json--full {
  width: 100%;
  height: calc(100vh - 180px);
  overflow: auto;
}
.history-list {
  padding: 10px;
  margin-right: 10px;
}
.history-list-item {
  color: #fff;
  height:40px;
  line-height:40px;
  background-color: #ccc;
  margin-bottom: 10px;
  cursor: pointer;
  transition: all .3s cubic-bezier(0.165, 0.84, 0.44, 1);
}
.history-list-item span {
  display: block;
}
.history-list-item:hover, 
.history-list-item--active {
  background-color: rgba(255,161,161,1);
}

cmenu .menu-list li {
  display: flex;
  justify-content: space-between;
}
nmenu #nm-tag {
  font-size: 14px;
  margin-top: 16px;
  text-align: left;
}
nmenu #nm-icon {
  font-size: 14px;
  text-align: left;
}
nmenu input {
  padding: 6px;
  font-size: 12px;
}
</style>
